package com.mcxx.modules.miniSalvation.check.service.write;

import com.mcxx.constant.DictConstant;
import com.mcxx.modules.base.utils.DictionaryUtil;
import com.mcxx.modules.base.utils.QueryParamUtil;
import com.mcxx.modules.base.utils.excel.ImportExcel;
import com.mcxx.modules.filemanage.easypoi.util.ExportExcelService;
import com.mcxx.modules.filemanage.file.service.FileService;
import com.mcxx.modules.miniSalvation.check.dao.read.DepartmentDataReadDao;
import com.mcxx.modules.miniSalvation.check.dao.write.DepartmentDataWriteDao;
import com.mcxx.modules.miniSalvation.check.dto.DepartmentDataDTO;
import com.mcxx.modules.miniSalvation.check.dto.DepartmentDataExcelDTO;
import com.mcxx.modules.miniSalvation.check.dto.ExcelDepartmentDataDTO;
import com.mcxx.modules.miniSalvation.check.entity.DepartmentDataEntity;
import com.mcxx.modules.miniSalvation.check.param.DepartmentDataSearchParam;
import com.mcxx.modules.miniSalvation.check.service.read.DepartmentDataReadService;
import com.mcxx.modules.miniSalvation.family.dto.MessageDTO;
import com.mcxx.modules.miniSalvation.order.service.write.OrderCertWriteService;
import com.mcxx.modules.system.entity.TaskExportEntity;
import com.mcxx.modules.system.service.write.TaskExportWriteService;
import com.mcxx.result.BaseResult;
import com.mcxx.util.*;
import com.yinhai.ta404.component.audit.vo.ExcelInfo;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.service.BaseService;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import com.yinhai.ta404.module.dict.entity.TaDictCache;
import com.yinhai.ta404.module.dict.service.read.DictCacheService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service
@TaTransactional
public class DepartmentDataWriteService extends BaseService {

    private static Logger logger = LoggerFactory.getLogger(DepartmentDataWriteService.class);
    @Autowired
    private DepartmentDataReadService departmentDataReadService;
    @Autowired
    private DepartmentDataWriteDao departmentDataWriteDao;
    @Autowired
    private DepartmentDataReadDao dataReadDao;
    @Autowired
    private DictCacheService dictCacheService;
    @Autowired
    private FileService fileService;
    @Autowired
    private ExportExcelService exportExcelService;
    @Autowired
    private TaskExportWriteService taskExportWriteService;
    @Autowired
    private OrderCertWriteService orderCertWriteService;


    public int inserts(List<DepartmentDataEntity> entities){
        return departmentDataWriteDao.inserts(entities);
    }


    public BaseResult<MessageDTO> importDepartmentData(MultipartFile file, InputStream is) {
        BaseResult<MessageDTO> result = new BaseResult<>();

        HashSet<String> errorColumn = new HashSet<>();

        HashSet<String> errorIdcard = new HashSet<>();

        HashSet<String> repeatIdcard = new HashSet<>();

        HashSet<String> errorArea = new HashSet<>();

        HashSet<String> errorOrigin = new HashSet<>();

        HashSet<String> idcardSet = new HashSet<>();

        TaDictCache originTypeCache = dictCacheService.getCodeCache(DictConstant.DATA_ORIGRIN_TYPE);

        List<ExcelDepartmentDataDTO> dtos = ImportExcel.readExcel(ExcelDepartmentDataDTO.class, file, is, false);
        int total = dtos.size();
        logger.info("excel内容：" + dtos);
        if (CollectionUtils.isEmpty(dtos)) {
            result.setMsg("数据为空");
            logger.info("excel数据为空");
            return result;
        }

        Collections.reverse(dtos);
        for(int i = dtos.size()-1; i>=0; i--){
            ExcelDepartmentDataDTO dataDTO = dtos.get(i);

            if(CommonUtil.invalidArgs(dataDTO.getCounty(),dataDTO.getCommunity(),dataDTO.getStreet())){
                if(StringUtils.isNotEmpty(dataDTO.getIdcard())){
                    errorColumn.add(dataDTO.getIdcard());
                }
                dtos.remove(dataDTO);
                continue;
            }

            String idcard = dataDTO.getIdcard();
            if(idcardSet.contains(idcard)){
                dtos.remove(dataDTO);
                continue;
            }else {
                idcardSet.add(idcard);
            }

            if (!IdCardUtil.identityCardVerification(idcard).getData()) {
                logger.info("{}身份证正则校验失败",idcard);
                errorIdcard.add(idcard);
                dtos.remove(dataDTO);
                continue;
            }

            int count = departmentDataReadService.selectCountById(idcard);
            if(count>0){
                repeatIdcard.add(idcard);
                dtos.remove(dataDTO);
                continue;
            }

            int areaCount = departmentDataReadService.selectCountByArea(dataDTO.getCounty(),dataDTO.getStreet(),dataDTO.getCommunity());
            if(areaCount != 1){
                errorArea.add(idcard);
                dtos.remove(dataDTO);
                continue;
            }
            String areaCode = departmentDataReadService.selectAreaCodeByArea(dataDTO.getCounty(),dataDTO.getStreet(),dataDTO.getCommunity());
            dataDTO.setAreaCode(areaCode);

            String originTypeCode = DictionaryUtil.getDictBylabel(dataDTO.getOriginType()==null?"":dataDTO.getOriginType(),originTypeCache.getList()).getValue();
            if(StringUtils.isEmpty(originTypeCode)){
                errorOrigin.add(idcard);
                dtos.remove(dataDTO);
                continue;
            }
            dataDTO.setOriginType(originTypeCode);
        }
        int success = 0;

        if(dtos.size()>0){
           List<DepartmentDataEntity> entities = new ArrayList<>();
           for(ExcelDepartmentDataDTO dto : dtos){
               DepartmentDataEntity entity = convertToDepartmentDataEntity(dto);
               entities.add(entity);
           }
            success = departmentDataWriteDao.inserts(entities);
        }
        StringBuffer errorMsg = new StringBuffer();
        if(errorColumn.size()>0){
            errorMsg.append(errorColumn.toString()).append("必填字段缺失;");
        }
        if(errorIdcard.size()>0){
            errorMsg.append(errorIdcard.toString()).append("身份证校验失败;");
        }
        if(repeatIdcard.size()>0){
            errorMsg.append(repeatIdcard.toString()).append("身份证重复;");
        }
        if(errorArea.size()>0){
            errorMsg.append(errorArea.toString()).append("找不到地区信息;");
        }
        if(errorOrigin.size()>0){
            errorMsg.append(errorOrigin.toString()).append("数据来源错误;");
        }
        result.setMsg("一共"+total+"条数据,"+"成功导入"+success+"条;"+errorMsg.toString());
        return result;
    }


    public static DepartmentDataEntity convertToDepartmentDataEntity(ExcelDepartmentDataDTO dto){
        DepartmentDataEntity entity = new DepartmentDataEntity();
        BeanUtils.copyProperties(dto, entity);
        return entity;
    }

    public ExcelInfo downLoadDepartmentData(DepartmentDataSearchParam param, UserAccountVo accountVo){

        QueryParamUtil.setBaseParamValue(param,accountVo);
        ExcelInfo excelInfo = null;
        List<DepartmentDataExcelDTO> list = dataReadDao.exportListByParam(param);
        excelInfo = exportExcelService.exportOrgOpLogs(DepartmentDataExcelDTO.class,list,"横向部门数据信息.xls",
                "横向部门数据列表","横向部门数据列表",false);

        return excelInfo;
    }

    public String deletObjectData(List<String> ids){
        String resMsg = "";
        int deleteSize = 0;

        List<DepartmentDataDTO> dataDTOS = departmentDataReadService.selectObjectInCheck(ids);
        if(CollectionUtils.isNotEmpty(dataDTOS)){
            List<String> checkingIds = dataDTOS.stream().map(o->o.getId()).collect(Collectors.toList());
            List<String> checkingIdcard = dataDTOS.stream().map(o->o.getIdcard()).collect(Collectors.toList());
            resMsg += "身份证为"+String.join(",",checkingIdcard)+"的数据在核对中，无法删除;";
            ids = ids.stream().filter(o-> !checkingIds.contains(o)).collect(Collectors.toList());
        }

        if(CollectionUtils.isNotEmpty(ids)){
            deleteSize = departmentDataWriteDao.deleteBatch(ids);

            for(String id: ids){
                orderCertWriteService.deleteByOrderId(id);
            }
        }
        resMsg += "成功删除"+deleteSize+"条记录";
        return resMsg;
    }
}
